package com.guochuang.yunwang.promanager.interceptors;

import com.alibaba.fastjson.JSONObject;
import com.guochuang.yunwang.promanager.annotation.CancelLoginIntercept;
import com.guochuang.yunwang.promanager.exception.AccessForbiddenException;
import com.guochuang.yunwang.promanager.utils.ProjectConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;


import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 登录拦截器
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private StringRedisTemplate redistemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 放行options请求
        if("OPTIONS".equals(request.getMethod())){
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 获取访问的方法
        Method method = handlerMethod.getMethod();
        // 获取该方法上的Cancel注解
        CancelLoginIntercept cancelInterceptor = method.getAnnotation(CancelLoginIntercept.class);
        // 首先判断该请求是否直接放行
        if(cancelInterceptor != null){
            return true;
        }
        Cookie[] cookies = request.getCookies();

        String username = null;
        String htoken = null;

        if(cookies==null){
            throw new AccessForbiddenException(ProjectConstant.USER_LOGIN_INVALID);
        }


        for (Cookie cookie : cookies) {
            if("vue_projectmanager_account".equals(cookie.getName())){
                username = cookie.getValue();
            }

            if("vue_projectmanager_token".equals(cookie.getName())){
                htoken = cookie.getValue();
            }
        }

        // 根据用户名查询token
        if(username == null || "".equals(username)){
            throw new AccessForbiddenException(ProjectConstant.ACCESS_FORBID_FAILED);
        }
        ValueOperations<String, String> strredis = redistemplate.opsForValue();

        // 从redis中获取token
        String userinfo = strredis.get(username);

        // 判空处理
        if(userinfo == null){
            throw new AccessForbiddenException(ProjectConstant.USER_LOGIN_INVALID);
        }

        JSONObject jsonObject = JSONObject.parseObject(userinfo);

        String token = jsonObject.getString("token");

        if(token == null){
            throw new AccessForbiddenException(ProjectConstant.ACCESS_FORBID_FAILED);
        }
        if(!Objects.equals(htoken,token)){
            throw new AccessForbiddenException(ProjectConstant.ACCESS_FORBID_FAILED);
        }
        // 这里需要将token重新保存，刷新存储时间
        strredis.set(username,userinfo,1, TimeUnit.HOURS);

        return true;
    }
}
